import com.sl.core.domain.dto.JsonMappingFieldDefine;
import com.sl.core.engine.transfer.MappingFiledDefineToJoltDslTransfer;
import org.junit.jupiter.api.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class MappingFiledDefineToJoltDslTransferTest {

    // 测试空输入
    @Test
    void testTransferWithEmptyInput() {
        List<JsonMappingFieldDefine> fieldDefineList = Collections.emptyList();
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);
        assertEquals("", result);
    }

    // 测试单节点映射
    @Test
    void testTransferSingleNode() {
        JsonMappingFieldDefine field = new JsonMappingFieldDefine();
        field.setFieldCode("name");
        field.setFieldName("name");
        field.setMappingJsonPath("$.name");
        field.setIsArrayFlag(false);

        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(field);
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        String expected = "[\n" +
                "{\n" +
                "'operation': 'shift',\n" +
                "'spec': {\n" +
                "'name':['name']\n" +
                "}\n" +
                "}\n" +
                "]";


        assertEquals(expected.replaceAll("\\s+", ""), result.replaceAll("\\s+", ""));
    }

    // 测试嵌套节点映射
    @Test
    void testTransferNestedNodes() {
        // 创建父节点
        JsonMappingFieldDefine parent = new JsonMappingFieldDefine();
        parent.setFieldCode("user");
        parent.setFieldName("user");
        parent.setMappingJsonPath("$.user");
        parent.setIsArrayFlag(false);

        // 创建子节点
        JsonMappingFieldDefine child = new JsonMappingFieldDefine();
        child.setFieldCode("name");
        child.setFieldName("name");
        child.setMappingJsonPath("$.user.name");
        child.setIsArrayFlag(false);
        child.setParent(parent);

        parent.setChildren(Collections.singletonList(child));
        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(parent);

        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        String expected = "[\n" +
                "{\n" +
                "'operation': 'shift',\n" +
                "'spec': {\n" +
                "'user':{\n" +
                "'name':['user.name']\n" +
                "}\n" +
                "}\n" +
                "}\n" +
                "]";

        assertEquals(expected.replaceAll("\\s+", ""), result.replaceAll("\\s+", ""));
    }

    // 测试数组节点映射
    @Test
    void testTransferArrayNode() {
        JsonMappingFieldDefine field = new JsonMappingFieldDefine();
        field.setFieldCode("items");
        field.setFieldName("items");
        field.setMappingJsonPath("$.items[*]");
        field.setIsArrayFlag(true);

        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(field);
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        String expected = "[\n" +
                "{\n" +
                "'operation': 'shift',\n" +
                "'spec': {\n" +
                "'items':{\n" +
                "'*':{\n" +
                "['items[&1]']\n" +
                "}\n" +
                "}\n" +
                "}\n" +
                "}\n" +
                "]";

        assertEquals(expected.replaceAll("\\s+", ""), result.replaceAll("\\s+", ""));
    }

    // 测试复杂路径映射
    @Test
    void testTransferComplexPath() {
        JsonMappingFieldDefine field = new JsonMappingFieldDefine();
        field.setFieldCode("ge");
        field.setFieldName("ge");
        field.setMappingJsonPath("$.user[*].address[*].person.pwd[*].add.ge");
        field.setIsArrayFlag(false);

        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(field);
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        // 验证结果包含正确的路径引用
        assertTrue(result.contains("user[&3].address[&2].person.pwd[&1].add.ge"));
    }

    // 测试多路径映射
    @Test
    void testTransferMultiplePaths() {
        JsonMappingFieldDefine field1 = new JsonMappingFieldDefine();
        field1.setFieldCode("name");
        field1.setFieldName("name");
        field1.setMappingJsonPath("$.name");
        field1.setIsArrayFlag(false);

        JsonMappingFieldDefine field2 = new JsonMappingFieldDefine();
        field2.setFieldCode("age");
        field2.setFieldName("age");
        field2.setMappingJsonPath("$.age");
        field2.setIsArrayFlag(false);

        List<JsonMappingFieldDefine> fieldDefineList = Arrays.asList(field1, field2);
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        // 验证结果包含两个字段的映射
        assertTrue(result.contains("'name':['name']"));
        assertTrue(result.contains("'age':['age']"));
    }

    // 测试多级嵌套数组
    @Test
    void testTransferNestedArrays() {
        JsonMappingFieldDefine parent = new JsonMappingFieldDefine();
        parent.setFieldCode("users");
        parent.setFieldName("users");
        parent.setMappingJsonPath("$.users[*]");
        parent.setIsArrayFlag(true);

        JsonMappingFieldDefine child = new JsonMappingFieldDefine();
        child.setFieldCode("items");
        child.setFieldName("items");
        child.setMappingJsonPath("$.users[*].items[*]");
        child.setIsArrayFlag(true);
        child.setParent(parent);

        parent.setChildren(Collections.singletonList(child));
        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(parent);

        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        // 验证结果包含正确的多级数组引用
        assertTrue(result.contains("users[&2].items[&1]"));
    }

    // 测试addBuild方法
    @Test
    void testAddBuild() {
        String mappingJsonPath = "$.user[*].address[*].city";
        List<JsonMappingFieldDefine> source = Collections.emptyList();

        // 由于addBuild是私有方法，我们通过transfer方法间接测试
        JsonMappingFieldDefine field = new JsonMappingFieldDefine();
        field.setMappingJsonPath(mappingJsonPath);
        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(field);

        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        // 验证生成的Jolt表达式是否正确处理了数组引用
        assertTrue(result.contains("user[&2].address[&1].city"));
    }

    // 测试findTarget方法
    @Test
    void testFindTarget() {
        // 创建测试数据
        JsonMappingFieldDefine target1 = new JsonMappingFieldDefine();
        target1.setMappingPath("$.user.name");

        JsonMappingFieldDefine target2 = new JsonMappingFieldDefine();
        target2.setMappingPath("$.user.age");

        List<JsonMappingFieldDefine> convertRelationDTO = Arrays.asList(target1, target2);

        // 由于findTarget是私有方法，我们通过其他方法间接测试
        JsonMappingFieldDefine field = new JsonMappingFieldDefine();
        field.setPath("$.user.name");
        field.setChildren(Collections.emptyList());

        // 构建一个包含该字段的列表并转换
        List<JsonMappingFieldDefine> fieldDefineList = Collections.singletonList(field);
        String result = MappingFiledDefineToJoltDslTransfer.transfer(fieldDefineList);

        // 验证结果是否包含正确的映射
        assertTrue(result.contains("'user.name'"));
    }
}